home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / CHNLTST / SPSCTST.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  16.5 KB  |  590 lines

  1. ;+
  2. ; Edit History
  3. ;
  4. ; Nov-25-91 ml.    The ACSI DMA channel will be used in the Sparrow's
  5. ;        SCSI.  (Argh!)  So, code is modified to talk to the
  6. ;        5380 through wdl and wdc.  This means Sparrow's SCSI
  7. ;        inherited all the restrictions of ACSI, except for
  8. ;        the opcode of a command (now we get all 8 bits.)
  9. ;        This is a merge of acsi.s and scsi.s of v5.00.
  10. ;
  11. ; Dec-10-91 ml.    Don't need to have extra long timeout in _rcvspscsi()
  12. ;        and _wrtspscsi() because extended read and write are 
  13. ;        not supported due to the 8 bit counter in the DMAC.
  14. ;
  15. ; Jan-27-92 ml.    Try optimizing it.
  16. ;        *NOTE*  Do NOT use 'move.l's to select the SCSI 
  17. ;            registers and write data to them.  It is
  18. ;            because 680x0 writes the high word first.
  19. ;            So, writing a long word to WDCWDL means
  20. ;            writing the data before pointing to the
  21. ;            correct register.  In the ACSI code, the
  22. ;            move.l's are writing data to the previous
  23. ;            address, and setting up the address for
  24. ;            the next access.  It was confusing, and it
  25. ;            is not done here.
  26. ;
  27. ; Jan-28-92 ml.    In order for AHDI to work at IPL 7, Timer C is used
  28. ;        instead of hz_200 for timeout purposes.
  29. ;
  30. ; Feb-12-92 ml.    Modified to use the "flush" bit and the extended counter.
  31. ;-
  32.  
  33.  
  34. .include    "defs.h"
  35. .include    "sysvar.h"
  36. .include    "mfp.h"
  37. .include    "acsi.h"
  38. .include    "spscsi.h"
  39. .include    "macros.h"
  40. .include    "68030.s"
  41.  
  42. ;+
  43. ; Command length
  44. ;-
  45. NCMD    equ    6        ; length of short command (in bytes)
  46.  
  47.  
  48. .if    !DRIVER            ; not to be included in driver
  49. scxltmout:  dc.l    12001   ; SCSI extra long-timeout (>1 min)
  50. slwsclto:   dc.l    5000    ; SCSI long-timeout (>25 S) for stunit()
  51. slwscsto:   dc.l    42        ; SCSI short-timeout (>205 mS) for stunit()
  52. scltmout:   dc.l    201        ; SCSI long-timeout (>1000 ms)
  53. scstmout:   dc.l    101        ; SCSI short-timeout (>500 ms)
  54. rcaltm:        dc.l    801        ; time for drive recalibration (>4s)
  55. .else    ;!DRIVER
  56. .extern    scxltmout, slwsclto, slwscsto, scltmout, scstmout, rcaltm
  57. .endif    ;!DRIVER
  58.  
  59. ;+
  60. ; For Chnltst only
  61. .extern    blit, blittst
  62. .extern    idespin, idespnup
  63. ;-
  64.  
  65.  
  66. .extern    setadma, setacnt, _hdone
  67. stat:        dc.w    0        ; status byte
  68. flush:        dc.b    0        ; flush flag
  69. .even
  70.  
  71. ;+
  72. ; smplspscsi() - send a simple SCSI command (ie. no DMA involved)
  73. ;
  74. ;    d0.w = physical unit number
  75. ;    d1.l = transfer length (in bytes)
  76. ;    d2.w = command length (NCMD or LCMD)
  77. ;    a0.l = buffer address
  78. ;-
  79.     .globl    _smplspscsi
  80. _smplspscsi:
  81.     st    flock
  82.     andi.w    #7,d0            ; mask off the flags to get unit num
  83.     bsr    sblkspscsi        ; send command block
  84.     tst.w    d0            ; successful?
  85.     bmi.s    .0            ; if not, go clean up
  86.     bsr    w4spstat        ; else wait for status
  87. .0:    RSCSI    #SPSCSIREI,d1        ; clear potential interrupt
  88.     bra    _hdone            ; go clean up
  89.  
  90.  
  91.  
  92. ;+
  93. ; rcvspscsi() - send a SCSI command which receives data back.
  94. ;
  95. ; Passed:
  96. ;    d0.w = physical unit number
  97. ;    d1.l = transfer length (in bytes)
  98. ;    d2.w = command length (NCMD or LCMD)
  99. ;    a0.l = buffer address
  100. ;-
  101.     .extern    _cachexst
  102.     .globl    _rcvspscsi
  103. _rcvspscsi:
  104.     st    flock            ; lock FIFO
  105.     andi.w    #7,d0            ; mask off the flags to get unit num
  106.     movem.l    d1-d2/a0,-(sp)        ; save buffer address and cmd length
  107.     bsr    sblkspscsi        ; send command block
  108.     movem.l    (sp)+,d1-d2/a0        ; restore buffer address and cmd len
  109.     tst.w    d0            ; successful?
  110.     bmi    rspend            ; if not successful, return
  111.  
  112. ;+
  113. ; Feb-13-1992    Check whether FIFO needs to be flushed.
  114.     sf    flush            ; assume no need to flush
  115.     move.l    d1,d0            ; d0 = transfer length
  116.     andi.l    #$0f,d0            ; multiple of 16?
  117.     beq.s    rdma0            ; if so, no need to flush
  118.     st    flush            ; else, set flush flag
  119. ;-
  120.  
  121. rdma0:    WSCSI    #0,#SPSCSIICR        ; deassert the data bus
  122.     WSCSI    #1,#SPSCSITCR        ; set data in phase
  123.     RSCSI    #SPSCSIREI,d0        ; clear potential interrupt
  124.  
  125. .if    SPSCDMA                ; Set up the DMAC for data transfer
  126. ;    cmpi.l    #512,d1            ; transferring >= 512 bytes?
  127. ;    bcs    rpio            ; if not, do programmed IO
  128. ;                    ; else set up DMA chip for DMA
  129.  
  130.     WSCSI    #2,#SPSCSIMR        ; enable DMA mode
  131.      movea.l    #WDC,a1            ; a1 = pointer to DMA chip
  132.     bsr    setadma            ; set DMA pointer
  133.     move.w    #$190,XWDL(a1)    ;WDL    ; toggle DMA chip for "receive"
  134.     RSTDELAY            ; delay
  135.     move.w    #$090,XWDL(a1)    ;WDL
  136.     RSTDELAY            ; delay
  137.     bsr    setacnt
  138.  
  139. rdma1:    btst.b    #STA,WDSR        ; wait till it's safe to access
  140.     bne.s    rdma1            ;  the DMA channel
  141.  
  142. ;    TMOUT    #2,d0            ; delay before using DMA channel
  143. ;    CNTALL    d0
  144.  
  145.     WSCSI    #0,#SPSCSIDIR        ; start the DMA receive
  146.     move.w    #0,WDL
  147.  
  148. ;+
  149. ; Dec-10-1991    ml.    Don't need to have extra long timeout because
  150. ;            extended read and write are not supported due
  151. ;            to the 8 bit counter in the DMAC.
  152. ;
  153. ; Feb-13-1992    ml.    Put code back in because DMAC has been modified
  154. ;            to have a 14-bit counter.
  155.     moveq    #0,d0            ; assume no extra timeout
  156.     cmpi.w    #NCMD,d2        ; is this a long command?
  157.     beq.s    rdma2            ; if not, just go on
  158.     move.l    scxltmout,d0        ; set up an extra long timeout
  159. ;-
  160.  
  161. rdma2:    
  162. ;+
  163. ; for chnltst
  164.     tst.b    blit            ; do BLiT test?
  165.     beq.s    rdma22            ; if not, go wait for interrupts
  166.     bsr    blittst            ; else do the test
  167.  
  168.     tst.b    idespin            ; do IDE spin-down?
  169.     beq.s    rdma22            ; if not, go wait for interrupts
  170.     bsr    idespnup
  171. rdma22:
  172. ;-
  173.     bsr    w4spint            ; wait for interrupts
  174.     tst.w    d0            ; successful?
  175.     bne.s    rspend            ; if error, returns
  176.  
  177. ;+
  178. ; Feb-13-1992    ml.    Added code to use the flush bit on the DMAC.
  179. ;            Now, we can do DMA without sending a command
  180. ;            multiple times, to write everything from the 
  181. ;            FIFO to memory, for transfers of non-multiple
  182. ;            of 16 bytes.  Using this flush function requires
  183. ;            the buffer provided for the command to be as big 
  184. ;            as the closest multiple of 16 to receive all data.
  185. ;            
  186.     tst.b    flush            ; need to flush FIFO?
  187.     beq.s    rdma3            ; if not, proceed    
  188.     move.w    #$0020,WDL        ; else flush (Whoosh!)
  189. ;-
  190. rdma3:    tst.b    _cachexst        ; is there a cache to flush?
  191.     beq.s    rstat            ; if not, go get status
  192.     move    sr,-(sp)        ; go to IPL 7
  193.     ori    #$700,sr        ; no interrupts right now kudasai
  194.     movecacrd0            ; d0 = (cache control register)
  195.     ori.w    #$808,d0        ; dump both the D and I cache
  196.     moved0cacr            ; update cache control register
  197.     move    (sp)+,sr        ; restore interrupt state
  198.     bra.s    rstat            ; go read status 
  199. .endif    ;SPSCDMA
  200.  
  201. rpio:    movea.l    a0,a1            ; a1 -> buffer to read into
  202. rnxtb:    bsr    w4spdreq        ; wait for REQ for data to come
  203.     bmi.s    rspend            ; if timed out, returns
  204.     RSCSI    #SPSCSIDSR,d0        ; still in data in phase?
  205.     btst    #3,d0            
  206.     beq    rstat            ; if not, go get status
  207.     RSCSI    #bSPSCSI,d0        ; else read the next data byte
  208.     move.b    d0,(a1)+    
  209.     bsr    dospack
  210.     bra.s    rnxtb            ; do next byte
  211. rstat:    bsr    w4spstat        ; go get status byte
  212. rspend:    RSCSI    #SPSCSIREI,d1        ; clear potential interrupt
  213.     bra    _hdone            ; go clean up
  214.  
  215.  
  216.  
  217. ;+
  218. ; wrtspscsi() - send a SCSI command which will write data to the target
  219. ;
  220. ; Passed:
  221. ;    d0.w = physical unit number
  222. ;    d1.l = transfer length (in bytes)
  223. ;    d2.w = command length (NCMD or LCMD)
  224. ;    a0.l = buffer address
  225. ;
  226. ; Comments: 
  227. ; 12/04/89 ml
  228. ;    Bus error occurs when doing a write to the disk that ends at top
  229. ; of memory.  The DMA counter is decremented when the bytes are written 
  230. ; from the ping pong buffers to the device, not when bytes are grapped 
  231. ; from RAM to the ping pong buffers.  Well, AFTER the last 8 bytes are 
  232. ; read into the ping pong buffers and BEFORE they are written to the 
  233. ; device, the chip will attempt to read the NEXT 8 bytes into the ping 
  234. ; pong buffers which results in a bus error because it will be reading 
  235. ; pass top of memory.  To get around this HARDWARE BUG, the code will 
  236. ; ALWAYS handshake the last 8 bytes over instead of DMAing them.
  237. ;
  238. ; 01/23/90 ml
  239. ;    A. Pratt said he's willing to move the screen down and sacrifice
  240. ; 16 bytes of memory.  So, code added on 12/04/89 is commented out.
  241. ;-
  242.     .globl    _wrtspscsi
  243. _wrtspscsi:
  244.     st    flock            ; lock FIFO
  245.     andi.w    #7,d0            ; mask off the flags to get unit num
  246.  
  247.     movem.l    d1-d2/a0,-(sp)        ; save beginning buffer address
  248.     bsr    sblkspscsi        ; send command block
  249.     movem.l    (sp)+,d1-d2/a0        ; a0 = where DMA ends
  250.     tst.w    d0            ; successful?
  251.     bmi    wspend            ; if not, go clean up
  252.  
  253.     WSCSI    #0,#SPSCSITCR        ; set data out phase
  254.     RSCSI    #SPSCSIREI,d0        ; clear potential interrupt
  255.  
  256. .if    SPSCDMA
  257.                     ; Set up the DMAC for data transfer
  258.     cmpi.l    #512,d1            ; transferring >= 512 bytes?
  259.     bcs    wpio            ; if not, do programmed IO
  260.                     ; else do DMA
  261.     WSCSI    #2,#SPSCSIMR        ; enable DMA mode
  262.  
  263.     movea.l    #WDC,a1            ; a1 = pointer to DMA chip
  264.  
  265.     bsr    setadma            ; set DMA pointer
  266.     move.w    #$90,XWDL(a1)    ;WDL    ; toggle DMA chip for "send"
  267.     RSTDELAY            ; delay 
  268.     move.w    #$190,XWDL(a1)    ;WDL
  269.     RSTDELAY            ; delay
  270.     bsr    setacnt            ; set DMA count
  271.  
  272. wdma0:    btst.b    #STA,WDSR        ; wait till it's safe to access
  273.     bne.s    wdma0            ;  the DMA channel
  274.  
  275. ;    TMOUT    #2,d0            ; delay before using DMA channel
  276. ;    CNTALL    d0
  277.  
  278.     WSCSI    #0,#($100|SPSCSIDS)    ; start the DMA send
  279.     move.w    #$100,WDL
  280.  
  281. ;+
  282. ; Dec-10-1991    ml.    Don't need to have extra long timeout because
  283. ;            extended read and write are not supported due
  284. ;            to the 8 bit counter in the DMAC.
  285. ;
  286.     moveq    #0,d0            ; assume no extra timeout
  287.     cmpi.w    #NCMD,d2        ; is this a long command?
  288.     beq.s    wdma1            ; if not, just go on
  289.     move.l    scxltmout,d0        ; set up an extra long timeout
  290. ;-
  291.  
  292. wdma1:
  293. ;+
  294. ; for chnltst
  295.     tst.b    blit            ; do BLiT test?
  296.     beq.s    wdma11            ; if not, go wait for interrupts
  297.     bsr    blittst            ; else do the test
  298. wdma11:
  299. ;-
  300.     bsr    w4spint            ; wait for interrupts
  301.     tst.w    d0
  302.     beq.s    wstat            ; if ok, wait for status byte
  303.     bra.s    wspend            ; else return
  304. .endif    ;SPSCDMA
  305.                     ; hand shake data over the bus
  306. wpio:    movea.l    a0,a1            ; a1 -> buffer to write from
  307. wnxtb:    bsr    w4spdreq        ; wait for REQ for data to come
  308.     bmi.s    wspend            ; if timed out, returns
  309.     RSCSI    #SPSCSIDSR,d0
  310.     btst    #3,d0            ; still in data out phase?
  311.     beq.s    wstat            ; if not, go get status
  312.     moveq    #0,d0
  313.     move.b    (a1)+,d0        ; write the next data byte
  314.     WSCSI    d0,#bSPSCSI
  315.     bsr    dospack
  316.     bra.s    wnxtb            ; do next byte
  317. wstat:    bsr    w4spstat        ; get status byte
  318. wspend:    RSCSI    #SPSCSIREI,d1        ; clear potential interrupt
  319.     bra    _hdone            ; go clean up
  320.  
  321.  
  322.  
  323. ;+
  324. ; sblkspscsi() - set DMA pointer and count and send command block
  325. ;
  326. ; Passed:
  327. ;    d0.w = physical unit number
  328. ;    d1.l = transfer length (in bytes)
  329. ;    d2.w = command length (NCMD or LCMD)
  330. ;    a0.l = buffer address
  331. ;
  332. ; Returns:
  333. ;    d0.l =  0 if successful
  334. ;    d0.l = -1 if timeout
  335. ;-
  336.     .extern    _cmdblk
  337. sblkspscsi:
  338.     movem.l    d1-d2/a0,-(sp)        ; preserve d1, d2 and a0
  339.     move.w    d0,-(sp)        ; physical unit #
  340.     bsr    selspscsi        ; select the unit
  341.     addq.l    #2,sp            ; clean up stack
  342.     movem.l    (sp)+,d1-d2/a0        ; restore d1, d2 and a0
  343.     tst.w    d0            ; selection successful?
  344.     bmi.s    sbspend            ; if timed out, return
  345.                     ; else proceed
  346.     WSCSI    #2,#SPSCSITCR        ; assert C/D
  347.     WSCSI    #1,#SPSCSIICR        ; assert data bus
  348.  
  349.     lea    _cmdblk,a1        ; a1 -> command block
  350.     subq.w    #1,d2            ; dbra likes one less
  351. sbs0:    bsr    w4spreq            ; wait for REQ to come
  352.     bmi.s    sbspend            ; if timed out, returns
  353.     move.b    (a1)+,d0        ; d0.b = byte to be sent
  354.     WSCSI    d0,#SPSCSIDB        ; write a byte out to data bus
  355.     bsr    dospack            ; assert ACK
  356.     dbra    d2,sbs0            ; until whole command block is sent
  357.     moveq    #0,d0            ; all operations successful
  358. sbspend: rts                ; heading home
  359.  
  360.  
  361. ;+
  362. ; BOOLEAN selspscsi(SCSIUnit) 
  363. ; WORD SCSIUnit;
  364. ;-
  365. selspscsi:
  366.     TMOUT    scstmout,d1        ; set up a short timeout
  367.     move.w    #SPSCSICR,WDL
  368. .0:    move.w    WDC,d0
  369.     btst    #6,d0            ; STILL busy from last time?
  370.     beq.s    .1            ; if not, it's available
  371.     CNTDN1    d1,.0            ; else if not timed-out, wait longer
  372.     bra    .3            ; else, return error
  373.  
  374. .1:    WSCSI    #0,#SPSCSITCR        ; data out phase
  375.     WSCSI    #0,#SPSCSIISR        ; no interrupt from selection
  376.     WSCSI    #$0c,#SPSCSIICR        ; assert BSY and SEL
  377. ; set dest SCSI IDs
  378.     clr.w    d0
  379.     move.w    4(sp),d1        ; get the SCSI unit desired
  380.     bset    d1,d0            ; set the appropriate bit
  381.     WSCSI    d0,#SPSCSIODR        ; (real code would set ours too)
  382.  
  383. ;    WSCSI    #$0d,#SPSCSIICR        ; assert BUSY, SEL and data bus
  384.     WSCSI    #$05,#SPSCSIICR        ; assert SEL and data bus
  385.     RSCSI    #SPSCSIMR,d0        ; read Mode Register
  386.     andi.b    #$fe,d0            ; clear arbitrate bit
  387.     move.w    d0,WDC
  388.     RSCSI    #SPSCSIICR,d0        ; read Initiator Command Register
  389.     andi.b    #$f7,d0            ; clear BUSY
  390.     move.w    d0,WDC
  391.     nop                ; 2 deskew delays
  392.     nop
  393.  
  394.     TMOUT    scstmout,d1        ; set up timeout counter
  395.     move.w    #SPSCSICR,WDL
  396. .2:    move.w    WDC,d0            ; wait for bus to be busy
  397.     btst    #6,d0
  398.     bne.s    .4
  399.  
  400.     CNTDN1    d1,.2            ; if not timed-out, wait some more
  401.  
  402. .3:    moveq    #-1,d0            ; time out
  403.     bra.s    .5
  404.     
  405. .4:    clr.w    d0            ; selection successful
  406. .5:    WSCSI    #0,#SPSCSIICR        ; clear SEL and data bus assertion
  407.     rts
  408.  
  409.  
  410. ;+
  411. ; VOID resetspscsi();
  412. ;
  413. ; Feb-14-1992    ml.    Added code to reset DMAC before talking through
  414. ;            it to reset the SCSI bus.  To protect DMAC from
  415. ;            locking up, check if it's safe to access it
  416. ;            before doing any of the above.
  417. ;-
  418.     .globl    resetspscsi
  419.     .extern    setscstmout
  420.     .extern    setscltmout
  421. resetspscsi:
  422. rst0:    btst.b    #STA,WDSR    ; wait till it's safe to access
  423.     bne.s    rst0        ;  the DMA channel
  424.  
  425.     move.w    #$190,WDL    ; reset DMA chip
  426.     RSTDELAY        ; delay
  427.     move.w    #$090,WDL
  428.     RSTDELAY
  429.                 ; reset SCSI bus
  430.     WSCSI    #$80,#SPSCSIICR    ; assert RST
  431. ;    TMOUT    scstmout,d1    ; wait (at least) 250 ms
  432. ;    CNTALL    d1
  433.     bsr    setscstmout    ; wait (at least) 250 ms
  434. .0:    cmp.l    (a0),d1
  435.     bhi.s    .0
  436. ;    move.w    #0,WDC
  437.     WSCSI    #0,#SPSCSIICR    ; clear RST
  438. ;    TMOUT    scltmout,d1    ; wait (at least) 1000 ms
  439. ;    CNTALL    d1
  440.     bsr    setscltmout    ; wait (at least) 1000 ms
  441. .1:    cmp.l    (a0),d1
  442.     bhi.s    .1
  443.     rts
  444.  
  445.  
  446. ;+
  447. ; w4spint - wait for interrupts from 5380 or DMAC during DMA tranfers
  448. ;
  449. ; Returns:
  450. ;    d0.l = returned status or timeout error
  451. ;
  452. ; Comments:
  453. ;    When 5380 is interrupted, it indicates a change of data to
  454. ; status phase (i.e., DMA is done), or ...
  455. ;    When DMAC is interrupted, it indicates either DMA count is
  456. ; zero, or there is an internal bus error.
  457. ;-
  458. w4spint:
  459.     TMOUT    rcaltm,d1        ; set timeout (incl. recalibration)
  460.     add.l    d0,d1
  461. .0:    btst    #5,GPIP            ; interrupt?
  462.     beq.s    .1            ; active LOW
  463.     CNTDN1    d1,.0            ; if there's more time, keep waiting
  464.                     ; else timed-out
  465.     bsr    resetspscsi        ; reset the SCSI bus
  466.     moveq    #-1,d0            ; return timeout
  467.     bra.s    w4spiend
  468.  
  469. .1:    moveq    #0,d0            ; DMA is successful
  470.     RSCSI    #SPSCSIREI,d1        ; clear potential interrupt
  471.     WSCSI    #0,#SPSCSIMR        ; disable DMA mode
  472.     WSCSI    #0,#SPSCSIICR        ; make sure data bus is not asserted
  473. w4spiend:
  474.     rts
  475.  
  476.  
  477. ;+
  478. ; w4spstat - wait for status byte and message byte.
  479. ;
  480. ; Returns:
  481. ;    d0.l = returned status or timeout error
  482. ;-
  483. w4spstat:
  484.     WSCSI    #3,#SPSCSITCR        ; status in phase
  485.     RSCSI    #SPSCSIREI,d0        ; clear potential interrupt
  486.  
  487.     bsr    w4spreq            ; wait for status byte
  488.     bmi.s    w4spend            ; if timed-out, returns
  489. gspstat:
  490.     RSCSI    #SPSCSIDB,d0        ; get the status byte
  491.     andi.w    #$ff,d0
  492.     move.w    d0,stat            ; save the status byte
  493.     bsr    dospack            ; signal that status byte is here
  494.  
  495. .1:    bsr    w4spreq            ; wait for message byte
  496.     bmi.s    w4spend            ; if timed-out, returns
  497.  
  498.     RSCSI    #SPSCSIDB,d0        ; get and ignore message byte
  499.     bsr    dospack            ; signal that message byte is here
  500.     move.w    stat,d0            ; recall the status byte
  501. w4spend:
  502.     rts                ; return
  503.  
  504.  
  505. ;+
  506. ; w4spdreq() - wait for REQ to come during hand shake of data bytes
  507. ; w4spreq() - wait for REQ to come during hand shake of non-data bytes
  508. ;
  509. ; Returns:
  510. ;     0 - if successful
  511. ;    -1 - times out
  512. ;-
  513. w4spdreq:
  514.     TMOUT    rcaltm,d1        ; add time for recalibration
  515.     bra.s    w4req0
  516. w4spreq:
  517.     TMOUT    scstmout,d1        ; set up timeout counter
  518. w4req0:    move.w    #SPSCSICR,WDL
  519. .1:    move.w    WDC,d0            ; read Control Register
  520.     btst    #5,d0            ; waiting for REQ to come
  521.     bne.s    .2            ; if REQ comes, done
  522.     CNTDN1    d1,.1            ; if there is more time, keep waiting
  523.     moveq    #-1,d0            ; else, returns timed out
  524.     bra.s    w4sprend
  525. .2:    moveq    #0,d0            ; returns successful
  526. w4sprend:
  527.     rts
  528.  
  529.  
  530. ;+
  531. ; dospack() - assert ACK
  532. ;
  533. ; Returns:
  534. ;     0 - always successful
  535. ;-
  536. dospack:    
  537.     RSCSI    #SPSCSIICR,d0        ; read Initiator Command Register
  538.     ori.b    #$11,d0            ; assert ACK (and data bus)
  539.     move.w    d0,WDC
  540.     andi.b    #$ef,d0            ; clear ACK
  541.     move.w    d0,WDC
  542.     moveq    #0,d0
  543.     rts
  544.  
  545.  
  546. .if    !DRIVER                ; not to be included in driver
  547.  
  548. ;+
  549. ; fmtspscsi() - format a SCSI unit
  550. ;
  551. ;    d0.w = physical unit number
  552. ;    d1.l = transfer length (in bytes)
  553. ;    d2.w = command length (NCMD or LCMD)
  554. ;    a0.l = buffer address
  555. ;-
  556.     .globl    _fmtspscsi
  557. _fmtspscsi:
  558.     andi.w    #7,d0            ; mask off the flags to get unit num
  559.     bsr    sblkspscsi        ; send command block
  560.     bpl.s    .0            ; if successful, wait for status byte
  561.     rts                ; else return
  562. .0:    WSCSI    #3,#SPSCSITCR        ; status in phase
  563.     RSCSI    #SPSCSIREI,d0        ; clear potential interrupt
  564. .1:    RSCSI    #SPSCSICR,d0        ; read Control Register
  565.     btst    #5,d0            ; wait forever for REQ to come
  566.  
  567.  
  568. .if    DEBUG
  569.  
  570.     bne.s    .3            ; For debugging purpose - 
  571.     move.l    #_hz_200,a0        ;    add a delay in this "tight" 
  572.     moveq    #2,d1            ;    loop to slow down SCSI chip 
  573.     add.l    (a0),d1            ;    accessing.
  574. .2:    cmp.l    (a0),d1
  575.     bhi.s    .2
  576.     bra.s    .1
  577.  
  578. .else    ;DEBUG
  579.  
  580.     beq.s    .1
  581.  
  582. .endif    ;DEBUG
  583.  
  584. .3:    bra    gspstat            ; when REQ comes, get status byte
  585.  
  586. .endif    ;!DRIVER
  587.  
  588.  
  589.  
  590.